package com.sc.nft.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sc.nft.dao.*;
import com.sc.nft.entity.DigitalCollection;
import com.sc.nft.entity.EquityProps;
import com.sc.nft.entity.SecondEquityPropsConfig;
import com.sc.nft.entity.vo.AdminSecondEquityPropsOrderListVO;
import com.sc.nft.entity.vo.AdminSecondEquityPropsPageVO;
import com.sc.nft.entity.vo.SecondConSignEquityPropsVO;
import com.sc.nft.enums.ConSignStatus;
import com.sc.nft.enums.SecondWantBuyOrderTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.AdminSecondEquityPropsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class AdminSecondEquityPropsServiceImpl implements AdminSecondEquityPropsService {

    private final SecondEquityPropsConfigDao secondEquityPropsConfigDao;
    private final SecondEquityPropsDao secondEquityPropsDao;
    private final SecondEquityPropsOrderDao secondEquityPropsOrderDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final EquityPropsDao equityPropsDao;
    private final WantBuyOrderDao wantBuyOrderDao;

    @Override
    public void addSecondEquityPropsConf(Long equityPropsId, SecondEquityPropsConfig secondEquityPropsConfig) {
        //校验是否存在
        Assert.isFalse(secondEquityPropsConfigDao.getIsExistByEquityPropsId(equityPropsId), () -> new GlobalRunTimeException("该凭证已有配置!"));

        secondEquityPropsConfig.setStatus(Boolean.FALSE);
        secondEquityPropsConfig.setBrandShow(Boolean.TRUE);
        secondEquityPropsConfig.setFirmShow(Boolean.TRUE);
        secondEquityPropsConfig.insert();
    }

    @Override
    public Page<AdminSecondEquityPropsPageVO> getPage(String firstTitle, Page page) {
        Page<AdminSecondEquityPropsPageVO> adminSecondEquityPropsPageVOPage = secondEquityPropsConfigDao.getPage(firstTitle, page);
        if (!CollectionUtils.isEmpty(adminSecondEquityPropsPageVOPage.getRecords())) {
            fillSecondOrderInfo(page.getRecords());
        }
        return adminSecondEquityPropsPageVOPage;
    }

    @Override
    public void editSecondCollection(SecondEquityPropsConfig secondEquityPropsConfig) {

        Assert.isTrue(
                secondEquityPropsConfigDao.editSecondCollection(secondEquityPropsConfig),
                () -> new GlobalRunTimeException("修改失败,请稍后重试"));
    }

    @Override
    public void updateStatusById(Long id, Boolean status) {
        SecondEquityPropsConfig secondEquityPropsConfig = secondEquityPropsConfigDao.getById(id);
        Assert.notNull(secondEquityPropsConfig, () -> new GlobalRunTimeException("未找到该配置"));

        Assert.isFalse(secondEquityPropsConfig.getStatus() == status, () -> new GlobalRunTimeException("状态未发生改变"));
        //下架 先校验是否有挂单的
        if (!status) {
            Assert.isTrue(secondEquityPropsDao.getIsExistByEquityPropsId(secondEquityPropsConfig.getEquityPropsId()), () -> new GlobalRunTimeException("此凭证还有存在上架中的 不能下架"));
            Assert.isTrue(CollectionUtil.isEmpty(wantBuyOrderDao.releaseList(SecondWantBuyOrderTypeEnum.EQUITY_PROPS, secondEquityPropsConfig.getEquityPropsId())), () -> new GlobalRunTimeException("当前有求购订单，无法进行下架"));
        }

        Assert.isTrue(secondEquityPropsConfigDao.updateStatusById(id, status), () -> new GlobalRunTimeException("修改失败,请稍后重试"));
    }

    @Override
    public Page<SecondConSignEquityPropsVO> adminConSignPage(String userTel, Date startTime, ConSignStatus status, Date endTime, Page page) {
        return secondEquityPropsDao.adminConSignPage(userTel, startTime, ObjectUtil.isNull(status) ? 0 : status.getCode(), endTime, page);
    }

    @Override
    public Page<AdminSecondEquityPropsOrderListVO> adminDealEquityPropsPage(String buyUserTel, String salesUserTel, String firstTitle, Date startTime, Date endTime, Date dealStartTime, Date dealEndTime, Page page) {
        return secondEquityPropsOrderDao.adminDealEquityPropsPage(page, buyUserTel, salesUserTel, firstTitle, startTime, endTime, dealStartTime, dealEndTime);
    }

    @Override
    public void updateSortById(Long id, Integer sort) {
        Assert.isTrue(secondEquityPropsConfigDao.updateSortById(id, sort), () -> new GlobalRunTimeException("修改失败,请稍后重试"));
    }

    @Override
    public SecondEquityPropsConfig getSecondEquityPropsConf(Long id) {
        return secondEquityPropsConfigDao.getById(id);
    }

    private void fillSecondOrderInfo(List<AdminSecondEquityPropsPageVO> records) {
        List<Long> wantBuyHoldCollectionIdList = records.stream()
                .filter(Objects::nonNull)
                .map(AdminSecondEquityPropsPageVO::getWantBuyHoldCollectionId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<DigitalCollection> digitalCollectionList = CollectionUtil.isNotEmpty(wantBuyHoldCollectionIdList) ? digitalCollectionDao.listByIds(wantBuyHoldCollectionIdList) : Lists.newArrayList();
        Map<Long, DigitalCollection> digitalCollectionMap = CollectionUtil.isNotEmpty(digitalCollectionList) ? digitalCollectionList.stream().collect(Collectors.toMap(DigitalCollection::getId, Function.identity())) : Maps.newHashMap();

        List<Long> wantBuyConsumePropIdList = records.stream()
                .filter(Objects::nonNull)
                .map(AdminSecondEquityPropsPageVO::getWantBuyConsumePropId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<EquityProps> equityPropsList = CollectionUtil.isNotEmpty(wantBuyConsumePropIdList) ? equityPropsDao.listByIds(wantBuyConsumePropIdList) : Lists.newArrayList();
        Map<Long, EquityProps> equityPropsMap = CollectionUtil.isNotEmpty(equityPropsList) ? equityPropsList.stream().collect(Collectors.toMap(EquityProps::getId, Function.identity())) : Maps.newHashMap();

        records.stream()
                .filter(Objects::nonNull)
                .forEach(sc -> {
                    if (Objects.nonNull(sc.getWantBuyHoldCollectionId())) {
                        DigitalCollection digitalCollection = digitalCollectionMap.get(sc.getWantBuyHoldCollectionId());
                        if (Objects.nonNull(digitalCollection)) {
                            sc.setWantBuyHoldCollectionName(digitalCollection.getFirstTitle());
                        }
                    }
                    if (Objects.nonNull(sc.getWantBuyConsumePropId())) {
                        EquityProps equityProps = equityPropsMap.get(sc.getWantBuyConsumePropId());
                        if (Objects.nonNull(equityProps)) {
                            sc.setWantBuyConsumePropName(equityProps.getFirstTitle());
                        }
                    }
                });
    }

}
